package com.study.controller;

import cn.hutool.core.util.StrUtil;
import com.study.bean.UserInfo;
import com.study.service.UserInfoService;
import com.study.service.UserService;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.groups.Default;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhuzi
 * 2023/8/11 14:26
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/")
@RequiredArgsConstructor
public class UserInfoHandler {
    private final UserInfoService userInfoService;

    private final UserService userService;

    @GetMapping("/getByName")
    public String getByName(String name) {
        return name + "ok;";
    }

    @GetMapping("addUser")
    public String addUser(@Valid UserInfo userInfo, BindingResult bindingResult) {
        System.out.println(userInfo);
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach(error -> {
                System.out.println(StrUtil.format("{}{}|{}", error.getObjectName(), error.getDefaultMessage()));
            });

            bindingResult.getFieldErrors().forEach(fieldError -> {
                System.out.println(StrUtil.format("{}|{}|{}没通过校验规则的值是:", fieldError.getObjectName(), fieldError.getField(),
                        fieldError.getDefaultMessage(), fieldError.getRejectedValue()));

            });
        }
        return "提交成功";
    }

    /**
     * 原生Valid 不支持分组校验
     * spring提供的支持分组校验
     */
    @GetMapping("addUser2")
    public String addUser2(@Validated(value = {UserInfo.Add.class, Default.class}) UserInfo userInfo,
                           BindingResult bindingResult) {
        System.out.println(userInfo);
        if (bindingResult.hasErrors()) {
            bindingResult.getFieldErrors().forEach(fieldError -> {
                System.out.println(StrUtil.format("{}|{}|{}没通过校验规则的值是:", fieldError.getObjectName(), fieldError.getField(),
                        fieldError.getDefaultMessage(), fieldError.getRejectedValue()));

            });
            return "校验不通过";
        }
        return "提交成功";
    }

    /**
     * 在每个Controller 写 ExceptionHandler 可以处理当前controller抛出的异常
     *
     * @return {@link String}
     */
    @ExceptionHandler(BindException.class)
    public String handleEx(BindException e) {
        List<FieldError> fieldErrors = e.getFieldErrors();
        return fieldErrors.stream().map(fe -> StrUtil.format("属性:{} 校验不通过,原因:{}\n", fe.getField(), fe.getDefaultMessage())).collect(Collectors.joining(","));
    }

    /**
     * 单个参数校验，需要在类上添加 @Validated 。 https://zhuanlan.zhihu.com/p/387010936
     *
     * @param name
     * @param code
     * @return
     */
    @ApiOperation(value = "校验单个参数", notes = "校验单个参数测试")
    @GetMapping("param")
    public String param(String name, @Length(max = 5, message = "编码长度不能超过20") @RequestParam String code) {
        return StringUtils.repeat(name, 2) + code;
    }

    @GetMapping("nobean")
    public String nobean() {
        String random = RandomStringUtils.randomAlphanumeric(5);
        log.info("random[{}]", random);
        //random = RandomStringUtils.random(2, 0x4e00, 0x3fa5, false, false);
        log.info("random[{}]", random);
        return userService.testValid(random);
        //userInfoService.testValid(random);
    }
}
